package com.xsystem.api.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xsystem.api.Api;

public final class MessagesUtil {

	private MessagesUtil() {
	}

	private static final HashMap<String, Properties> propertiesMap = new HashMap<String, Properties>();

	private static final Logger log = LoggerFactory.getLogger(MessagesUtil.class);

	public static Map<String, Object> prepareErrorResponse(String errorCode, String errorMsg) {
		HashMap<String, Object> hm = new HashMap<String, Object>();
		hm.put(Api.OUT_STATUS, Api.Status.FAILED.toString());
		hm.put(Api.OUT_ERROR_CODE, errorCode);
		hm.put(Api.OUT_MESSAGE, errorMsg);
		return hm;
	}

	public static Map<String, Object> prepareErrorResponseWithParams(Map<String, Object> responseMap,
			String msg) {
		Map<String, Object> hm = new HashMap<String, Object>();
		hm.put(Api.OUT_STATUS, Api.Status.FAILED.toString());
		if (msg != null) {
			hm.put(Api.OUT_MESSAGE, msg);
		}
		if (responseMap != null) {
			hm.putAll(responseMap);
		}
		return hm;
	}

	public static Map<String, Object> prepareSuccessResponse(Map<String, Object> responseMap, String msg) {
		Map<String, Object> hm = new HashMap<String, Object>();
		hm.put(Api.OUT_STATUS, Api.Status.OK.toString());
		if (msg != null) {
			hm.put(Api.OUT_MESSAGE, msg);
		}
		if (responseMap != null) {
			hm.putAll(responseMap);
		}
		return hm;
	}

	public static Map<String, Object> prepareWarningResponse(Map<String, Object> responseMap, String msg) {
		Map<String, Object> hm = new HashMap<String, Object>();
		hm.put(Api.OUT_STATUS, Api.Status.WARNING.toString());
		if (msg != null) {
			hm.put(Api.OUT_MESSAGE, msg);
		}
		if (responseMap != null) {
			hm.putAll(responseMap);
		}
		return hm;
	}

	public static Map<String, Object> prepareFailedResponse(Map<String, Object> responseMap, String errorCode,
			String msg) {
		Map<String, Object> hm = new HashMap<String, Object>();
		hm.put(Api.OUT_STATUS, Api.Status.FAILED.toString());
		hm.put(Api.OUT_ERROR_CODE, errorCode);
		if (msg != null) {
			hm.put(Api.OUT_MESSAGE, msg);
		}
		if (responseMap != null) {
			hm.putAll(responseMap);
		}
		return hm;
	}

	public static String getProperty(Class<? extends Object> apiClass, String key, String languageCode,
			String... parameters) {
		if (languageCode == null || languageCode.equals("")) {
			languageCode = "en";
		}

		String filePath = getPropertyFilePath(apiClass, languageCode);

		Properties properties = propertiesMap.get(filePath);
		if (properties == null) {
			properties = loadPropertiesFromFile(filePath);
			if (properties == null) {
				int index = languageCode.indexOf("_");
				if (index != -1) {
					return getProperty(apiClass, key, languageCode.substring(0, index), parameters);
				} else {
					log.error("(Missing language pack: " + filePath + ") :: " + languageCode);
					return getProperty(apiClass, key, null, parameters);
				}
			} else {
				propertiesMap.put(filePath, properties);
			}
		}

		String value = properties.getProperty(key);
		if (value != null) {
			for (int i = 0; i < parameters.length; i++) {
				value = value.replace("{" + i + "}", parameters[i]);
			}
		}
		return value;
	}

	private static String getPropertyFilePath(Class<? extends Object> apiClass, String languageCode) {
		String directory = apiClass.getProtectionDomain().getCodeSource().getLocation().getPath();
		String packagePath = apiClass.getPackage().getName().replace('.', File.separatorChar);
		String packageName = packagePath.substring(packagePath.lastIndexOf(File.separatorChar));
		if (directory.endsWith(".class")) {
			directory = directory.substring(0, directory.lastIndexOf('/'));
			packagePath = "";
		}
		return directory + packagePath + packageName + "_" + languageCode + ".properties";
	}

	private static Properties loadPropertiesFromFile(String filePath) {
		Properties properties = null;
		FileInputStream fis = null;
		InputStreamReader isr = null;
		try {
			fis = new FileInputStream(filePath);
			isr = new InputStreamReader(fis, "UTF-8");
			properties = new Properties();
			properties.load(isr);
		} catch (IOException e) {
			// log.error(e.getMessage());
		} finally {
			if (isr != null) {
				try {
					isr.close();
				} catch (IOException e) {
					log.error(e.getMessage());
				}
			}
		}
		return properties;
	}

}
